 <template xmlns="http://www.w3.org/1999/html">
    <el-table :data="filterTableData" style="width: 100%" height="650px">
      <el-table-column label="序号" width="60px" type="index" />
      <el-table-column label="任务名称" width="140px"  prop="name" show-overflow-tooltip/>
      <el-table-column label="目标网址"  prop="targetUrl" show-overflow-tooltip/>
      <el-table-column label="执行时间" width="200px" show-overflow-tooltip>
        <template #default="scope">{{ formattedExecutionTime(scope.row.executionTime) }}</template>
      </el-table-column>
      <el-table-column label="状态" width="100px" prop="status" show-overflow-tooltip />
      <el-table-column label="爬取网页类型" width="120px">
        <template #default="scope">{{ formattedCrawlType(scope.row.crawlType) }}</template>
      </el-table-column>
      <el-table-column align="right" width="270px">
        <template #header>
          <el-input v-model="search" size="small" placeholder="Type to search" />
        </template>
        <template #default="scope">
          <div >

            <div v-if="scope.row.status==='爬取中'">
                <el-progress :percentage="scope.row.progress" />
            </div>
            <div v-else class="button-container">

          <el-button size="small" @click="handleEdit(scope.row.taskId)"
          >编辑</el-button>

          <el-button v-if="scope.row.status==='爬取成功'"
                     size="small"
                     link
                     @click="handleOut(scope.row.taskId)"
          >导出数据</el-button>

          <el-button v-if="scope.row.status==='未开始'"
                     size="small"
                     link
                     @click="handlePublish(scope.row)"
          >发布任务</el-button>

          <el-button v-if="scope.row.status==='等待爬取'"
                     size="small"
                     type="warning"
                     @click="handleCancel(scope.row)"
          >取消任务</el-button>

          <el-button v-if="scope.row.status==='爬取错误'"
                      size="small"
                     type="warning"
                      @click="handleCancel(scope.row)"
          >重置任务</el-button>

          <el-button
              size="small"
              type="danger"
              @click="handleDelete(scope.row.taskId)"
          >删除</el-button>
              <div class="leftMargin">
                <el-icon  @click="handleUpdetaStatus(scope.row,true)">
                  <RefreshRight /></el-icon>
              </div>
          </div>

          </div>
        </template>
      </el-table-column>
    </el-table>


   <el-drawer v-model="drawer" title="网址配置" size="70%"  :before-close="handleClose">

<!--     一级配置-->
     <div>
       <el-form
           ref="form"
           :model="historyTask"
           label-width="auto"
           :label-position="'top'"
           :size="'default'"
       >
         <el-form-item label="爬虫名称">
           <el-input v-model="historyTask.name" />
         </el-form-item>

         <el-form-item label="爬虫网址(需要占位符的地方请留意)">
           <el-input v-model="historyTask.targetUrl" />
         </el-form-item>

         <el-form-item label="爬取网页类型">
           <el-select
               v-model="historyTask.crawlType"
               placeholder="静态网页 或者 动态网页"
           >
             <el-option label="静态网页" value="Static" />
             <el-option label="动态网页" value="Motion" />
           </el-select>
         </el-form-item>


         <el-form-item>
           <el-button type="primary" @click="historyTaskSubmit(historyTask)">保存</el-button>
           <el-button @click="innerDrawer = true">跳过</el-button>
         </el-form-item>
       </el-form>
     </div>

<!--     二级配置-->
     <div>
       <el-drawer
           v-model="innerDrawer"
           title="配置携带参数"
           :append-to-body="true"
           size="65%"
       >
         <el-form
             ref="form"
             :model="prefixInfos"
             label-width="auto"
             :label-position="'top'"
             :size="'small'"
             v-for="(item, index) in prefixInfos" :key="index"
         >
           <hr>
           <p>参数 {{ index+1 }}</p>
           <el-form-item label="设置携带信息类型">
             <el-select
                 v-model="item.type"
                 placeholder="header 或者 cookie"
             >
               <el-option label="header" value="header" />
               <el-option label="cookie" value="cookie" />
             </el-select>
           </el-form-item>
           <el-form-item label="key的值">
             <el-input v-model="item.header" />
           </el-form-item>
           <el-form-item label="value的值">
             <el-input v-model="item.headerValue" />
           </el-form-item>
           <el-button class="mb-4" @click.prevent="removePrefixInfo(item)"
           >Delete</el-button
           >
         </el-form>

         <el-button @click="prefixInfosSubmit(prefixInfos,historyTask.id)">保存</el-button>
         <el-button @click="addPrefixInfo(historyTask.id)">增加携带信息</el-button>
         <el-button @click="inner2Drawer = true">跳过</el-button>

<!--         三级配置-->
         <div>
           <el-drawer
               v-model="inner2Drawer"
               title="配置循环参数"
               :append-to-body="true"
               size="60%"
           >
             <el-form
                 ref="form"
                 :model="crawlFor"
                 label-width="auto"
                 :label-position="'top'"
                 :size="'default'"
             >
               <el-form-item label="爬取网址" >
               <el-card>
                 {{ historyTask.targetUrl }}
               </el-card>
               </el-form-item>
               <el-form-item label="循环类型" >
                 <el-select v-model="crawlFor.type" placeholder="三种循环方式">
                   <el-option label="数字自增" value="1" />
                   <el-option label="自定义循环方式" value="2" />
                   <el-option label="混合循环" value="3" />
                   <el-option label="动态点击循环（只用配置点击次数即步长）" value="4" />
                 </el-select>
               </el-form-item>

               <el-form-item label="数字自增循环开始下标" placeholder="开始下标" >
                 <el-input v-model="crawlFor.start" :disabled="crawlFor.type ==='4'" />
               </el-form-item>

               <el-form-item label="数字自增循环结束下标" placeholder="结束下标">
                 <el-input v-model="crawlFor.end" :disabled="crawlFor.type ==='4'"/>
               </el-form-item>

               <el-form-item label="数字自增循环步长" placeholder="循环步长">
                 <el-input v-model="crawlFor.step" />
               </el-form-item>

               <el-form-item label="自定义循环" placeholder="循环之间用‘@’分割">
                 <el-input v-model="crawlFor.typeArr" :disabled="crawlFor.type ==='4'"/>
               </el-form-item>

             </el-form>

             <el-button @click="crawlForSubmit(crawlFor,historyTask.id)">保存</el-button>
             <el-button @click="inner3Drawer = true">跳过</el-button>

<!--             四级配置-->
             <div>

               <el-drawer
                   v-model="inner3Drawer"
                   title="配置规则参数"
                   :append-to-body="true"
                   size="60%"
               >
                 <el-form
                     ref="form"
                     :model="rules"
                     label-width="auto"
                     :label-position="'top'"
                     :size="'default'"
                     v-for="(item, index) in rules" :key="index"
                 >
                   <hr>
                   <p>规则 {{ index+1 }}</p>

                   <el-form-item label="设置字段标题" placeholder="字段标题">
                     <el-input v-model="item.fieldTitle" :disabled="item.gainType ==='button'" clearable />
                   </el-form-item>

                   <el-form-item label="设置爬取数据的方式（id，tag，class，attr）">
                     <el-select
                         v-model="item.ruleType"
                         placeholder="id，tag，class，attr"
                         :disabled="item.gainType ==='button'"
                     >
                       <el-option label="id" value="id" />
                       <el-option label="class" value="class" />
                       <el-option label="tag" value="tag" />
                       <el-option label="attr" value="attr" />
                     </el-select>
                   </el-form-item>
                   <el-form-item label="具体的值（比如 类名 属性名）">
                     <el-input v-model="item.field" clearable/>
                   </el-form-item>
                   <el-form-item label="爬取那个值在第几位">
                     <el-input v-model="item.count" :disabled="item.gainType ==='button'" />
                   </el-form-item>

                   <el-form-item label="获取属性名的名称（选填 获取属性才用填写）">
                     <el-input v-model="item.fieldName" :disabled="item.gainType ==='button'" clearable/>
                   </el-form-item>
                   <el-form-item label="设置爬取数据的类型（比如文本，还是属性）">
                     <el-select
                         v-model="item.gainType"
                         placeholder="文本还是属性还是爬取中间块"
                     >
                       <el-option label="文本" value="text" />
                       <el-option label="属性" value="attr" />
                       <el-option label="爬取中间块" value="getAll" />
                       <el-option label="动态点击按钮" value="button" />
                     </el-select>
                   </el-form-item>

                   <el-button class="mb-4" @click.prevent="removeRules(item)"
                   >Delete</el-button
                   >
                 </el-form>

                 <el-button @click="rulesSubmit(rules,historyTask.id)">保存</el-button>
                 <el-button @click="addRules(historyTask.id)">增加规则信息</el-button>
                 <el-button @click="inner4Drawer = true">跳过</el-button>

                 <div>

                   <el-drawer
                       v-model="inner4Drawer"
                       title="配置开始时间参数"
                       :append-to-body="true"
                       size="60%"
                   >
                   <el-form
                       ref="form"
                       :model="history"
                       label-width="auto"
                       :label-position="'top'"
                       :size="'default'"
                   >
                       <el-card class="mb-4">
                         原来的时间为:    {{ formattedExecutionTime(history.executionTime) }}
                       </el-card>
                     <el-form-item label="开始时间">
                       <el-col :span="11">
                         <el-date-picker
                             v-model="history.startTime"
                             type="datetime"
                             label="选择开始的时间"
                             placeholder="选择开始的时间"
                             style="width: 100%"
                         />
                       </el-col>
                     </el-form-item>
                   </el-form>
                     <el-button @click="historySubmit(history)">保存</el-button>
                     <el-button @click="historyCancel (historyTask.id)">退出编辑</el-button>

                   </el-drawer>
                 </div>
               </el-drawer>
             </div>
           </el-drawer>
         </div>
       </el-drawer>
     </div>
   </el-drawer>

   <div class=" mt-10" >
     <el-pagination
         v-model:current-page="currentPage4"
         v-model:page-size="pageSize4"
         :page-sizes="[10, 20, 30, 40]"
         :small="small"
         :disabled="disabled"
         :background="background"
         layout="total, sizes, prev, pager, next, jumper"
         :total="total1"
         @size-change="handleSizeChange"
         @current-change="handleCurrentChange"
     />
   </div>
  </template>

  <script lang="ts" setup>
  import {computed, onMounted, reactive, ref} from 'vue'
  import {doGet,doPut,doDelete,doPost} from "../../api"
  import axios from "axios";
  import {ElMessage, ElMessageBox, ElNotification} from "element-plus";
  import {RefreshRight, Top} from "@element-plus/icons-vue";


  const total1=ref(10)
  const currentPage4 = ref(1)
  const pageSize4 = ref(10)
  const small = ref(false)
  const background = ref(false)
  const disabled = ref(false)
  const historyRecord=ref([])

  onMounted(() => {
    // 在组件挂载到页面之后执行的逻辑
    // 可以在这里调用加载数据的函数
    loadData();

  });

  //一级配置
  const drawer = ref(false)
  //二级配置
  const innerDrawer = ref(false)
  //三级配置
  const inner2Drawer = ref(false)
  //四级配置
  const inner3Drawer = ref(false)
  //五级配置
  const inner4Drawer = ref(false)

  const history = reactive({
    executionTime:'',
    startTime: '',
    taskId:''
  })
  const historyTask = reactive({
    id:'',
    name: '',
    targetUrl: '',
    crawlType:''
  })
  const prefixInfos = reactive([
    {
      header: '',
      headerValue: '',
      id: '',
      type: '',
      taskId:''
    }
  ])
  const rules = reactive([
    {
      count: 1,
      field: '',
      fieldName: '',
      fieldTitle: '',
      gainType: '',
      id: '',
      ruleType: '',
      taskId: ''
    }
  ])

  const crawlFor = reactive({
    end: '',
    start: '',
    step: '',
    taskId: '',
    type: '',
    typeArr: ''
  })


  function loadData() {
    doGet("/api/crawler/history/list/?currPage="+currentPage4.value+"&pageSize="+pageSize4.value,null,resp=>{
      historyRecord.value=resp.data.list
      currentPage4.value=resp.data.currPage
      pageSize4.value=resp.data.pageSize
      total1.value=resp.data.totalCount
    })

  }
  
  //格式化网站类型
  const formattedCrawlType = (crawlType) => {
    if (crawlType.toLowerCase().includes("Static".toLowerCase())){
      return "静态网页"
    }else {
      return "动态网页"
    }
  }

  // 创建一个计算属性来格式化执行时间
  const formattedExecutionTime = (timeString) => {
    const rawDate = new Date(timeString); // 创建 Date 对象

    // 明确声明 options 参数的类型为 Intl.DateTimeFormatOptions
    const options: Intl.DateTimeFormatOptions = {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    };

    return rawDate.toLocaleDateString('zh-CN', options); // 使用 'zh-CN' 格式
  };

    const search = ref('')
    const filterTableData = computed(() =>
        historyRecord.value.filter(
            (data) =>
                !search.value ||
                data.name.toLowerCase().includes(search.value.toLowerCase())
        )
    )
    const handleEdit = (index: number) => {
      console.log(index)
      doGet("/api/crawler/history/getOne?taskId="+index,null,resp=>{
        if (resp.code===1){

          Object.assign(historyTask, resp.data.historyTask);
          Object.assign(history, resp.data.history);
          Object.assign(rules, resp.data.rules);
          Object.assign(prefixInfos, resp.data.prefixInfos);
          Object.assign(crawlFor, resp.data.crawlFor);
        }else {
          ElMessage({
            message: '系统错误',
            type: 'error',
          })
        }
      })
      drawer.value = true
    }
    const historyTaskSubmit=(historyTask)=>{
      doPut("/api/crawler/historyTask/update",historyTask,resp=>{
          if (resp.code===1){
            ElMessage({
              message: '保存成功',
              type: 'success',
            })
            innerDrawer.value=true
            handleEdit(historyTask.id)
          }

      })
    }

  const addPrefixInfo = (Id) => {
    prefixInfos.push({
      header: '',
      headerValue: '',
      id: null,
      type: '',
      taskId: Id
    })
  }
  const removePrefixInfo = (item) =>{
    if (item.id!==null){
      ElMessageBox.confirm('这个是原来存在的数据，是否删除')
          .then(() => {
            doDelete("/api/crawler/prefixInfo/delete?id="+item.id,null,resp=>{
              if (resp.code===1){
                ElMessage({
                  message: resp.data,
                  type: 'success',
                })
              }
              const index = prefixInfos.indexOf(item)
              if (index !== -1) {
                prefixInfos.splice(index, 1)
              }
            })
          })
          .catch(() => {
            // catch error
          })
    }else {
      const index = prefixInfos.indexOf(item)
      if (index !== -1) {
        prefixInfos.splice(index, 1)
      }
    }

  }
  const prefixInfosSubmit=(prefixInfos,taskId)=>{
    doPut("/api/crawler/prefixInfo/update",prefixInfos,resp=>{
      if (resp.code===1){
        ElMessage({
          message: '保存成功',
          type: 'success',
        })
        handleEdit(taskId)
        inner2Drawer.value=true
      }

    })
  }

  const crawlForSubmit=(crawlFor,taskId)=>{

      crawlFor.taskId=taskId

    doPut("/api/crawler/crawlFor/update",crawlFor,resp=>{

      if (resp.code===1){
        ElMessage({
          message: '保存成功',
          type: 'success',
        })
        inner3Drawer.value=true
      }

    })

  }

  const addRules = (id) => {
    rules.push({
      count: 1,
      field: '',
      fieldName: '',
      fieldTitle: '',
      gainType: '',
      id: null,
      ruleType: '',
      taskId: id
    })

  }
  const removeRules=(item)=>{
    if (item.id!==null){
      ElMessageBox.confirm('这个是原来存在的数据，是否删除')
          .then(() => {
            doDelete("/api/crawler/rule/delete?id="+item.id,null,resp=>{
              if (resp.code===1){
                ElMessage({
                  message: resp.data,
                  type: 'success',
                })
              }
              const index = rules.indexOf(item)
              if (index !== -1) {
                rules.splice(index, 1)
              }
            })
          })
          .catch(() => {
            // catch error
          })
    }else {
      const index = rules.indexOf(item)
      if (index !== -1) {
        rules.splice(index, 1)
      }
    }
  }
  const rulesSubmit = (rules,taskId) => {
    doPut("/api/crawler/rule/update",rules,resp=>{
        if(resp.code===1){
          ElMessage({
            message: resp.data,
            type: 'success',
          })
          handleEdit(taskId)
        }
    })
  }

  const historySubmit = (history) => {
      formatStartTime(history.startTime)
      console.log(history.startTime)
      doPut("/api/crawler/history/update",history,resp=>{
          if (resp.code===1){
            ElMessage({
              message: resp.data,
              type: 'success',
            })
          }else {
            ElMessage({
              message: resp.msg,
              type: 'error',
            })
          }
      })
  }

  const historyCancel=(taskId)=>{
      loadData()
    drawer.value = false
    //二级配置
     innerDrawer.value = false
    //三级配置
    inner2Drawer.value = false
    //四级配置
    inner3Drawer.value = false
    //五级配置
     inner4Drawer.value = false

  }
  // 创建一个函数来格式化日期时间
  // 格式化函数，将时间转换为上海时区并添加时区信息
  const formatStartTime = (startTime) => {
    const year = startTime.getFullYear();
    const month = (startTime.getMonth() + 1).toString().padStart(2, '0');
    const day = startTime.getDate().toString().padStart(2, '0');
    const hours = startTime.getHours().toString().padStart(2, '0');
    const minutes = startTime.getMinutes().toString().padStart(2, '0');
    const seconds = startTime.getSeconds().toString().padStart(2, '0')

    // 构建带有时区信息的 ISO 8601 格式的日期时间字符串
    const isoDateTime = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;

    history.startTime = isoDateTime;
  };



  const handleOut = (index:number) => {
      console.log(index)
      axios({
        method: 'get',
        url: "/api/crawler/history/download?taskId="+index,
        responseType: 'blob', // 响应类型设置为 blob
      })
          .then((response) => {
            if (response.status === 200) {
              const contentDisposition = response.headers['content-disposition'];
              const match = contentDisposition.match(/filename="(.+)"/);
              let filename = 'file.xlsx'; // 默认文件名

              if (match && match[1]) {
                // 解码文件名
                filename = decodeURIComponent(match[1]);
                console.log(filename)
              }

              const blob = new Blob([response.data], { type: response.headers['content-type'] });
              const url = window["URL"].createObjectURL(blob);
              const a = document.createElement('a');
              a.href = url;
              a.download = filename;
              document.body.appendChild(a);
              a.click();
              window["URL"].revokeObjectURL(url);
            }
          })
          .catch((error) => {
            console.error('Axios error:', error);
          });

    }

    const handlePublish = (row) => {
        console.log(row)
        doGet("/api/crawler/history/publishTask?taskId="+row.taskId,null,resp=>{

          if (resp.data==="发布成功"){

            ElNotification({
              title: 'Success',
              message: resp.data,
              type: 'success',
              duration:2500
            })

            handleUpdetaStatus(row,false)
            
          }else {
            ElNotification({
              title: 'Error',
              message: '发布失败',
              type: 'error',
              duration:2500
            })
          }
        })

    }
    
    const handleUpdetaStatus = (row,flag) => {

        if (row.status==="爬取成功"){
            ElMessageBox.confirm('重置状态后，将不能导出数据，请先保存数据')
                .then(() => {
                  doGet("/api/crawler/history/resetStatus?taskId="+row.taskId,null,resp=>{
                    ElMessage({
                      message: resp.data,
                      type: 'success',
                    })
                  })
                  row.status="未开始"
                })
                .catch(() => {
                  // catch error
                })

        }else {

          doGet("/api/crawler/history/updateStatus?taskId="+row.taskId,null,resp=>{
            row.status=resp.data
            if (resp.data==="爬取中"){
              fetchData(row)
            }
            if (flag){
              ElMessage({
                message: '更新成功',
                type: 'success',
              })
            }

          })

        }


    }

    const handleCancel = (row) => {

        doGet("/api/crawler/history/resetStatus?taskId="+row.taskId,null,resp=>{

          if(resp.data==="重置成功"){
            ElMessage({
              message: '操作成功',
              type: 'success',
            })
            handleUpdetaStatus(row,false)
          }else {
            handleUpdetaStatus(row,false)
            ElMessage({
              message: resp.data,
              type: 'warning',
            })
          }
        })
    }

  const handleClose = (done: () => void) => {

    ElMessageBox.confirm('你有未保存的数据是否退出')
        .then(() => {
          loadData()
          done()
        })
        .catch(() => {
          // catch error
        })

  }
    const handleDelete = (index: number) => {
      console.log(index)
      ElMessageBox.confirm('是否删除爬虫历史记录')
          .then(() => {
            doDelete("/api/crawler/history/delete?taskId="+index,null,resp=> {
              if (resp.code === 1) {
                ElMessage({
                  message: resp.data,
                  type: 'success',
                })
                loadData()
              } else {
                ElMessage({
                  message: "删除失败",
                  type: 'error',
                })
              }
            })
          })
    }
    const handleSizeChange = (val: number) => {
      loadData();
      console.log(`${val} items per page`)
    }
    const handleCurrentChange = (val: number) => {
      loadData();
      console.log(`current page: ${val}`)
    }
  const fetchData = (row) => {


      setTimeout(() => {
        doGet("/api/crawler/history/getProgress?taskId="+row.taskId,null,resp=>{
          row.progress=resp.data
        })
        if (row.progress < 100 && row.status==="爬取中") {
          fetchData(row);
        }
        if( row.progress>=100 ||row.status!= "爬取中" ){
          handleUpdetaStatus(row,false)
        }
      }, 1000);

  };

  </script>


<style scoped>

.demo-pagination-block + .demo-pagination-block {
  margin-top: 10px;
}
.demo-pagination-block .demonstration {
  margin-bottom: 16px;
}
.button-container {
  display: flex;
  justify-content: flex-start; /* 或者使用其他水平对齐方式，如 space-between */
}
.leftMargin{
  margin-left: 20px;

}
</style>